layout managers: Handle native children
authorMatthias Clasen <mclasen@redhat.com>
Mon, 10 Jun 2019 18:01:59 +0000 (18:01 +0000)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 11 Jun 2019 18:52:30 +0000 (14:52 -0400)
Add a convenience api to skip children
that should not be included in the layout,
and call gtk_native_check_resize on all
native children outside of the vfunc.

docs/reference/gtk/gtk4-sections.txt
gtk/gtkbinlayout.c
gtk/gtkboxlayout.c
gtk/gtkfixedlayout.c
gtk/gtkgridlayout.c
gtk/gtklayoutmanager.c
gtk/gtkoverlaylayout.c
gtk/gtkwidget.c
gtk/gtkwidget.h

index bbb9d6a47595da29346c757615a6119c5f992dd1..5efb6214c5a5c047ad9ce94313c62e6f5d97c08a 100644 (file)
@@ -4552,6 +4552,7 @@ gtk_widget_insert_before
 gtk_widget_insert_after
 gtk_widget_set_layout_manager
 gtk_widget_get_layout_manager
+gtk_widget_should_layout
 
 <SUBSECTION>
 gtk_widget_get_path
index cbc35108924ccab649f695a6a1367904ae06f8cc..0b8e186c3f052a182f63419f4b198d745282f2cc 100644 (file)
@@ -57,7 +57,7 @@ gtk_bin_layout_measure (GtkLayoutManager *layout_manager,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      if (gtk_widget_get_visible (child))
+      if (gtk_widget_should_layout (child))
         {
           int child_min = 0;
           int child_nat = 0;
@@ -92,7 +92,7 @@ gtk_bin_layout_allocate (GtkLayoutManager *layout_manager,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      if (child && gtk_widget_get_visible (child))
+      if (child && gtk_widget_should_layout (child))
         gtk_widget_allocate (child, width, height, baseline, NULL);
     }
 }
index 98d87701ebad5db7469eb844c2860180504f9186..55ca7b481a09908c200abb9dc399e0a93b4aa09b 100644 (file)
@@ -174,16 +174,13 @@ count_expand_children (GtkWidget *widget,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      if (GTK_IS_NATIVE (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
-      if (_gtk_widget_get_visible (child))
-        {
-          *visible_children += 1;
+      *visible_children += 1;
 
-          if (gtk_widget_compute_expand (child, orientation))
-            *expand_children += 1;
-        }
+      if (gtk_widget_compute_expand (child, orientation))
+        *expand_children += 1;
     }
 }
 
@@ -223,10 +220,7 @@ gtk_box_layout_compute_size (GtkBoxLayout *self,
       int child_min = 0;
       int child_nat = 0;
 
-      if (GTK_IS_NATIVE (child))
-        continue;
-
-      if (!_gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       gtk_widget_measure (child, self->orientation,
@@ -300,20 +294,17 @@ gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      if (GTK_IS_NATIVE (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
-      if (_gtk_widget_get_visible (child))
-        {
-          gtk_widget_measure (child,
-                              self->orientation,
-                              -1,
-                              &sizes[i].minimum_size, &sizes[i].natural_size,
-                              NULL, NULL);
-
-          children_minimum_size += sizes[i].minimum_size;
-          i += 1;
-        }
+      gtk_widget_measure (child,
+                          self->orientation,
+                          -1,
+                          &sizes[i].minimum_size, &sizes[i].natural_size,
+                          NULL, NULL);
+
+      children_minimum_size += sizes[i].minimum_size;
+      i += 1;
     }
 
   if (self->homogeneous)
@@ -351,11 +342,7 @@ gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      if (GTK_IS_NATIVE (child))
-        continue;
-
-      /* If widget is not visible, skip it. */
-      if (!_gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       /* Assign the child's size. */
@@ -494,15 +481,6 @@ gtk_box_layout_allocate (GtkLayoutManager *layout_manager,
   gint child_size;
   gint spacing;
 
-  /* Handle native children first, and skip them in everything below */
-  for (child = _gtk_widget_get_first_child (widget);
-       child != NULL;
-       child = _gtk_widget_get_next_sibling (child))
-    {
-      if (GTK_IS_NATIVE (child))
-        gtk_native_check_resize (GTK_NATIVE (child));
-    }
-
   count_expand_children (widget, self->orientation, &nvis_children, &nexpand_children);
 
   /* If there is no visible child, simply return. */
@@ -527,10 +505,7 @@ gtk_box_layout_allocate (GtkLayoutManager *layout_manager,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      if (GTK_IS_NATIVE (child))
-        continue;
-
-      if (!_gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       gtk_widget_measure (child,
@@ -581,11 +556,7 @@ gtk_box_layout_allocate (GtkLayoutManager *layout_manager,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      if (GTK_IS_NATIVE (child))
-        continue;
-
-      /* If widget is not visible, skip it. */
-      if (!_gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       /* Assign the child's size. */
@@ -689,11 +660,7 @@ gtk_box_layout_allocate (GtkLayoutManager *layout_manager,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      if (GTK_IS_NATIVE (child))
-        continue;
-
-      /* If widget is not visible, skip it. */
-      if (!_gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       child_size = sizes[i].natural_size;
index 77e923add0477468c78b478c9d90ee59db608b37..f904c22c3fdcb65c1dae18bd3c1f14b4b0fc0dec 100644 (file)
@@ -238,7 +238,7 @@ gtk_fixed_layout_measure (GtkLayoutManager *layout_manager,
       int child_min_opp = 0, child_nat_opp = 0;
       graphene_rect_t min_rect, nat_rect;
 
-      if (!gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       child_info = GTK_FIXED_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (layout_manager, child));
@@ -291,7 +291,7 @@ gtk_fixed_layout_allocate (GtkLayoutManager *layout_manager,
     {
       GtkRequisition child_req;
 
-      if (!gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       child_info = GTK_FIXED_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (layout_manager, child));
index aa7bc69ed150e5dd8a5217ed7b1f134506357519..8d54367a7d551f21f7bf0f3fe13d4aa33e98f73f 100644 (file)
@@ -640,7 +640,7 @@ grid_request_non_spanning (GridRequest    *request,
       GtkGridLayoutChild *grid_child = get_grid_child (request->layout, child);
       GridChildAttach *attach;
 
-      if (!_gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       attach = &grid_child->attach[orientation];
@@ -778,7 +778,7 @@ grid_request_spanning (GridRequest    *request,
     {
       GtkGridLayoutChild *grid_child = get_grid_child (request->layout, child);
 
-      if (!_gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       attach = &grid_child->attach[orientation];
@@ -917,7 +917,7 @@ grid_request_compute_expand (GridRequest    *request,
     {
       GtkGridLayoutChild *grid_child = get_grid_child (request->layout, child);
 
-      if (!_gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       attach = &grid_child->attach[orientation];
@@ -939,7 +939,7 @@ grid_request_compute_expand (GridRequest    *request,
     {
       GtkGridLayoutChild *grid_child = get_grid_child (request->layout, child);
 
-      if (!_gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       attach = &grid_child->attach[orientation];
@@ -1497,7 +1497,7 @@ grid_request_allocate_children (GridRequest *request,
     {
       GtkGridLayoutChild *grid_child = get_grid_child (request->layout, child);
 
-      if (!_gtk_widget_get_visible (child))
+      if (!gtk_widget_should_layout (child))
         continue;
 
       allocate_child (request, GTK_ORIENTATION_HORIZONTAL, child, grid_child, &x, &width, &ignore);
index 1325c339ba3cc204f24e3705192682c85a719eec..c41a604b99a8f93bdec7fce89a233b9dbdd8ce30 100644 (file)
@@ -76,6 +76,7 @@
 #include "gtklayoutmanagerprivate.h"
 #include "gtklayoutchild.h"
 #include "gtkwidgetprivate.h"
+#include "gtknative.h"
 
 #ifdef G_ENABLE_DEBUG
 #define LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED(m,method)   G_STMT_START {  \
@@ -293,6 +294,20 @@ gtk_layout_manager_measure (GtkLayoutManager *manager,
     *natural_baseline = nat_baseline;
 }
 
+static void
+allocate_native_children (GtkWidget *widget)
+{
+  GtkWidget *child;
+
+  for (child = _gtk_widget_get_first_child (widget);
+       child != NULL;
+       child = _gtk_widget_get_next_sibling (child))
+    {
+      if (GTK_IS_NATIVE (child))
+        gtk_native_check_resize (GTK_NATIVE (child));
+    }
+}
+
 /**
  * gtk_layout_manager_allocate:
  * @manager: a #GtkLayoutManager
@@ -318,6 +333,8 @@ gtk_layout_manager_allocate (GtkLayoutManager *manager,
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (baseline >= -1);
 
+  allocate_native_children (widget);
+
   klass = GTK_LAYOUT_MANAGER_GET_CLASS (manager);
 
   klass->allocate (manager, widget, width, height, baseline);
index 4fa4f12dd8919423afb013cff23029f50cb06855..e0c65ba68abedaedd68fcc19e9d9268bfc9035a8 100644 (file)
@@ -252,6 +252,9 @@ gtk_overlay_layout_measure (GtkLayoutManager *layout_manager,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
+      if (!gtk_widget_should_layout (child))
+        continue;
+
       child_info = GTK_OVERLAY_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (layout_manager, child));
 
       if (child == main_widget || child_info->measure)
@@ -376,7 +379,7 @@ gtk_overlay_child_allocate (GtkOverlay            *overlay,
 {
   GtkAllocation child_allocation;
 
-  if (!gtk_widget_get_visible (widget))
+  if (!gtk_widget_should_layout (widget))
     return;
 
   gtk_overlay_compute_child_allocation (overlay, widget, child, &child_allocation);
index dc2d00c207751b0d0d7d3aaf0ccf558d16f7ca88..0bc88b06b21c1fd54ede7c25cb78ca8c5cce5e62 100644 (file)
@@ -13454,3 +13454,28 @@ gtk_widget_get_layout_manager (GtkWidget *widget)
 
   return priv->layout_manager;
 }
+
+/**
+ * gtk_widget_should_layout:
+ * @widget: a widget
+ *
+ * Returns whether @widget should contribute to
+ * the measuring and allocation of its parent.
+ * This is %FALSE for invisible children, but also
+ * for children that have their own surface.
+ *
+ * Returns: %TRUE if child should be included in
+ *   measuring and allocating
+ */
+gboolean
+gtk_widget_should_layout (GtkWidget *widget)
+{
+  if (!_gtk_widget_get_visible (widget))
+    return FALSE;
+
+  if (GTK_IS_NATIVE (widget))
+    return FALSE;
+
+  return TRUE;
+}
+
index 94586e22537cdb66d509d741e5dee109273cf2dc..bb2766078b008112879cb2d659827ccca4172914 100644 (file)
@@ -1026,6 +1026,9 @@ GDK_AVAILABLE_IN_ALL
 void                    gtk_widget_snapshot_child       (GtkWidget   *widget,
                                                          GtkWidget   *child,
                                                          GtkSnapshot *snapshot);
+GDK_AVAILABLE_IN_ALL
+gboolean                gtk_widget_should_layout        (GtkWidget   *widget);
+
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkWidget, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free)